View Javadoc
1   package org.apache.maven.surefire.testng.conf;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.lang.reflect.Method;
23  import java.util.ArrayList;
24  import java.util.HashMap;
25  import java.util.List;
26  import java.util.Map;
27  
28  import org.apache.maven.surefire.booter.ProviderParameterNames;
29  import org.apache.maven.surefire.testset.TestSetFailedException;
30  import org.testng.TestNG;
31  import org.testng.xml.XmlSuite;
32  
33  /**
34   * Configurator that relies on reflection to set parameters in TestNG
35   *
36   */
37  public abstract class AbstractDirectConfigurator
38      implements Configurator
39  {
40      final Map<String, Setter> setters;
41  
42      AbstractDirectConfigurator()
43      {
44          Map<String, Setter> options = new HashMap<String, Setter>();
45          // options.put( ProviderParameterNames.TESTNG_GROUPS_PROP, new Setter( "setGroups", String.class ) );
46          // options.put( ProviderParameterNames.TESTNG_EXCLUDEDGROUPS_PROP, new Setter( "setExcludedGroups", String.class
47          // ) );
48          options.put( "junit", new Setter( "setJUnit", Boolean.class ) );
49          options.put( ProviderParameterNames.THREADCOUNT_PROP, new Setter( "setThreadCount", int.class ) );
50          options.put( "usedefaultlisteners", new Setter( "setUseDefaultListeners", boolean.class ) );
51          this.setters = options;
52      }
53  
54      public void configure( TestNG testng, Map<String, String> options )
55          throws TestSetFailedException
56      {
57          System.out.println( "\n\n\n\nCONFIGURING TESTNG\n\n\n\n" );
58          // kind of ugly, but listeners are configured differently
59          final String listeners = options.remove( "listener" );
60          // DGF In 4.7, default listeners dump XML files in the surefire-reports directory,
61          // confusing the report plugin.  This was fixed in later versions.
62          testng.setUseDefaultListeners( false );
63          configureInstance( testng, options );
64          // TODO: we should have the Profile so that we can decide if this is needed or not
65          testng.setListenerClasses( loadListenerClasses( listeners ) );
66      }
67  
68      public void configure( XmlSuite suite, Map<String, String> options )
69          throws TestSetFailedException
70      {
71          Map<String, String> filtered = filterForSuite( options );
72          configureInstance( suite, filtered );
73      }
74  
75      protected Map<String, String> filterForSuite( Map<String, String> options )
76      {
77          Map<String, String> result = new HashMap<String, String>();
78          addPropIfNotNull( options, result, ProviderParameterNames.PARALLEL_PROP );
79          addPropIfNotNull( options, result, ProviderParameterNames.THREADCOUNT_PROP );
80          return result;
81      }
82  
83      private void addPropIfNotNull( Map<String, String> options, Map<String, String> result, String prop )
84      {
85          if ( options.containsKey( prop ) )
86          {
87              result.put( prop, options.get( prop ) );
88          }
89      }
90  
91      private void configureInstance( Object testngInstance, Map<String, String> options )
92      {
93          for ( Map.Entry<String, String> entry : options.entrySet() )
94          {
95              String key = entry.getKey();
96              String val = entry.getValue();
97              Setter setter = setters.get( key );
98              if ( setter != null )
99              {
100                 try
101                 {
102                     setter.invoke( testngInstance, val );
103                 }
104                 catch ( Exception e )
105                 {
106                     throw new RuntimeException( "Cannot set option " + key + " with value " + val, e );
107                 }
108             }
109         }
110     }
111 
112     static List<Class> loadListenerClasses( String listenerClasses )
113         throws TestSetFailedException
114     {
115         if ( listenerClasses == null || "".equals( listenerClasses.trim() ) )
116         {
117             return new ArrayList<Class>();
118         }
119 
120         List<Class> classes = new ArrayList<Class>();
121         String[] classNames = listenerClasses.split( "\\s*,\\s*(\\r?\\n)?\\s*" );
122         for ( String className : classNames )
123         {
124             Class<?> clazz = loadClass( className );
125             classes.add( clazz );
126         }
127 
128         return classes;
129     }
130 
131     static Class<?> loadClass( String className )
132         throws TestSetFailedException
133     {
134         try
135         {
136             return Class.forName( className );
137         }
138         catch ( Exception ex )
139         {
140             throw new TestSetFailedException( "Cannot find listener class " + className, ex );
141         }
142     }
143 
144     /**
145      * Describes a property setter by method name and parameter class
146      *
147      */
148     public static final class Setter
149     {
150         private final String setterName;
151 
152         private final Class<?> paramClass;
153 
154         public Setter( String name, Class<?> clazz )
155         {
156             setterName = name;
157             paramClass = clazz;
158         }
159 
160         public void invoke( Object target, String value )
161             throws Exception
162         {
163             Method setter = target.getClass().getMethod( setterName, paramClass );
164             if ( setter != null )
165             {
166                 setter.invoke( target, convertValue( value ) );
167             }
168         }
169 
170         private Object convertValue( String value )
171         {
172             if ( value == null )
173             {
174                 return null;
175             }
176             if ( paramClass.isAssignableFrom( value.getClass() ) )
177             {
178                 return value;
179             }
180 
181             if ( Boolean.class.equals( paramClass ) || boolean.class.equals( paramClass ) )
182             {
183                 return Boolean.valueOf( value );
184             }
185             if ( Integer.class.equals( paramClass ) || int.class.equals( paramClass ) )
186             {
187                 return new Integer( value );
188             }
189 
190             return value;
191         }
192     }
193 }